package com.kjc.demo.basic.util;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.stereotype.Component;

import java.io.*;

/**
 * @Author 刘强
 * @Time 2019年7月29日 上午9:40:36
 * @Version 1.0 Description: FTP 工具类
 */
@Component
@Slf4j
public class FTPUtil {
    private final static Integer port = 21;

    /**
     * 初始化ftp服务器
     */
    public FTPClient initFTPClient(String host, String username, String password) {
        FTPClient ftpClient = new FTPClient();
        ftpClient.setControlEncoding("utf-8");
        try {
            log.info("【FTP初始化】连接地址：{}, port:{}", host, port);
            ftpClient.connect(host, port); //连接ftp服务器
            ftpClient.login(username, password); //登录ftp服务器
            int replyCode = ftpClient.getReplyCode(); //是否成功登录服务器
            boolean flag = FTPReply.isPositiveCompletion(replyCode);
            if (!flag) {
                log.error("【FTP初始化】连接FTP失败，Host：{}, Port:{}, Username:{}, Password:{}", host, port, username, password);
                ftpClient.disconnect();
                return null;
            } else {
                log.info("【FTP初始化】连接FTP成功，Host：{}, Port:{}", host, port);
            }
        } catch (Exception e) {
            log.error("【FTP初始化】连接FTP异常！", e);
            return null;
        }
        return ftpClient;
    }

    /**
     * 上传文件
     *
     * @param path          ftp服务保存地址
     * @param fileName      上传到ftp的文件名
     * @param localFileUrl 待上传文件的名称（绝对地址）
     * @return
     */
    public boolean uploadFile(String host, String username, String password, String path, String fileName, String localFileUrl) {
        FTPClient ftpClient = null;
        InputStream inputStream = null;
        try {
            log.info("【FTP上传文件】开始上传文件，Path：{}, FileName:{}, localFileUrl:{}", path, fileName, localFileUrl);
            ftpClient = initFTPClient(host, username, password);
            if (ftpClient == null) {
                log.warn("【FTP上传文件】FTP初始化失败！Path：{}, FileName:{}, localFileUrl:{}", path, fileName, localFileUrl);
                return false;
            }
            ftpClient.setFileType(ftpClient.BINARY_FILE_TYPE);
            ftpClient.makeDirectory(path);
            ftpClient.changeWorkingDirectory(path);

            inputStream = new FileInputStream(new File(localFileUrl));
            boolean upBoolean = ftpClient.storeFile(fileName, inputStream);
            log.info("【FTP上传文件】上传文件结果：{}，Path：{}, FileName:{}, localFileUrl:{}", upBoolean, path, fileName, localFileUrl);
            return upBoolean;
        } catch (Exception e) {
            log.error("【FTP上传文件】上传文件异常！", e);
            return false;
        } finally {
            if (null != inputStream) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if ((ftpClient != null) && ftpClient.isConnected()) {
                try {
                    log.info("【FTP上传文件】登出!host：{}", host);
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 下载文件
     *
     * @param path      FTP服务器文件目录
     * @param fileName  文件名称
     * @param localPath 下载后的文件路径
     * @return
     */
    public boolean downloadFile(String host, String username, String password, String path, String fileName, String localPath) {
        FTPClient ftpClient = null;
        OutputStream os = null;
        try {
            log.info("【FTP下载文件】开始下载文件，Path：{}, FileName:{}, localPath:{}", path, fileName, localPath);
            ftpClient = initFTPClient(host, username, password);
            if (ftpClient == null) {
                log.warn("【FTP下载文件】FTP初始化失败！Path：{}, FileName:{}, localPath:{}", path, fileName, localPath);
                return false;
            }
            //切换FTP目录 
            ftpClient.changeWorkingDirectory(path);
            FTPFile[] ftpFiles = ftpClient.listFiles();
            for (FTPFile file : ftpFiles) {
                if (fileName.equalsIgnoreCase(file.getName())) {
                    File localFile = new File(localPath  + fileName);
                    os = new FileOutputStream(localFile);
                    boolean downBoolean = ftpClient.retrieveFile(file.getName(), os);
                    log.info("【FTP下载文件】下载文件成功，返回结果：{}, Path：{}, FileName:{}, localPath:{}", downBoolean, path, fileName, localPath);
                    return downBoolean;
                }
            }
            log.info("【FTP下载文件】下载的文件在FTP不存在！Path：{}, FileName:{}, localPath:{}", path, fileName, localPath);
            return false;
        } catch (Exception e) {
            log.error("【FTP下载文件】下载文件异常！", e);
            return false;
        } finally {
            if (null != os) {
                try {
                    os.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if ((ftpClient != null) && ftpClient.isConnected()) {
                try {
                    log.info("【FTP下载文件】登出!host：{}", host);
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除文件
     *
     * @param path     FTP服务器保存目录
     * @param fileName 要删除的文件名称
     * @return
     */
    public boolean deleteFile(String host, String username, String password, String path, String fileName) {
        FTPClient ftpClient = null;
        try {
            log.info("【FTP删除文件】开始删除文件，Path：{}, FileName:{}", path, fileName);
            ftpClient = initFTPClient(host, username, password);
            //切换FTP目录 
            ftpClient.changeWorkingDirectory(path);
            int dele = ftpClient.dele(fileName);
            log.info("【FTP删除文件】删除文件结果：{}, Path：{}, FileName:{}", dele, path, fileName);
            return true;
        } catch (Exception e) {
            log.error("【FTP删除文件】删除文件失败!Path：{}, FileName:{}", path, fileName, e);
            return false;
        } finally {
            if ((ftpClient != null) && ftpClient.isConnected()) {
                try {
                    log.info("【FTP删除文件】登出!host：{}", host);
                    ftpClient.logout();
                    ftpClient.disconnect();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

/*    public static void main(String[] args) {
        FTPUtil ftp = new FTPUtil();
        ftp.uploadFile("10.180.29.56","hxb","c3757870","/pub/test", "100000.txt", "F:/code/ftp/123456.txt");
        ftp.downloadFile("10.180.29.56","hxb","c3757870","/pub/test", "100000.txt", "F:/code/ftp/");
    }*/
}
